package com.pajx.testopengles.util

import android.opengl.Matrix

/**
 *User: RandBII
 *Date: 2020/8/19
 *Description:
 */
object MatrixStack {

    val mProjectionMatrix = FloatArray(16)
    val mViewMatrix = FloatArray(16)
    var mOptionMatrix = FloatArray(16)
    val mMVPMatrix = FloatArray(16)
    var stackTop = -1// 栈为空时  值-1

    /**
     * 2维数组
     */
    val mStack = Array(10) { FloatArray(16) }

    fun reset() {
        // 单位矩阵   计算之后还是原先的坐标值
        mOptionMatrix = floatArrayOf(
            1f, 0f, 0f, 0f,
            0f, 1f, 0f, 0f,
            0f, 0f, 1f, 0f,
            0f, 0f, 0f, 1f
        )
    }

    /**
     * 平移
     *
     * 在 x,y,z 上平移的距离
     */
    fun translate(x: Float, y: Float, z: Float) = Matrix.translateM(mOptionMatrix, 0, x, y, z)

    /**
     * deg: 旋转的角度
     * 绕  x,y , z
     *
     */
    fun rotate(deg: Float, x: Float, y: Float, z: Float) =
        Matrix.rotateM(mOptionMatrix, 0, deg, x, y, z)

    /**
     * 缩放  在  x,y,z 轴上的分量
     */
    fun scale(x: Float, y: Float, z: Float) = Matrix.scaleM(mOptionMatrix, 0, x, y, z)

    /**
     *  摄像机  cx,cy,cz
     *  目标点  tx,ty,tz
     *  摄像机up  upx,upy,upz
     */
    fun lookAt(
        cx: Float, cy: Float, cz: Float,
        tx: Float, ty: Float, tz: Float,
        upx: Float, upy: Float, upz: Float
    ) = Matrix.setLookAtM(mViewMatrix, 0, cx, cy, cz, tx, ty, tz, upx, upy, upz)

    /**
     * near 面的 left   left,
     */
    fun frustumM(left: Float, right: Float, bottom: Float, top: Float, near: Float, far: Float) =
        Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far)

    private fun submit() {
        Matrix.multiplyMM(
            mMVPMatrix, 0,
            mViewMatrix, 0,
            mOptionMatrix, 0
        )
        Matrix.multiplyMM(
            mMVPMatrix, 0,
            mProjectionMatrix, 0,
            mMVPMatrix, 0
        )

    }

    fun peek(): FloatArray {
        submit()
        return mMVPMatrix
    }


    /**
     * todo 和back 成对使用
     */
    fun save() {
        stackTop++
        System.arraycopy(mOptionMatrix, 0, mStack[stackTop], 0, mOptionMatrix.size)
    }

    /**
     * todo 和save 成对使用
     */
    fun back() {
        System.arraycopy(mStack[stackTop], 0, mOptionMatrix, 0, 16)
        stackTop--
    }


}